<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>数据类型</title>
</head>
<body>
    <script>
        "use strict";
        /*
            Javascript5种基本数据类型
                undefined null boolean number string
            1种复杂数据类型
                object
            
            typeof操作符：用来检测变量的数据类型
            对于一个值使用typeof操作符可能返回下列某个字符串：
                undefined-如果这个值未定义
                boolean-如果这个值是布尔值
                string-如果这个值是字符串
                number-如果这个值是数值
                object-如果这个值是对象或null
                function-如果这个值是函数

            undefined类型：
                这种类型只有一个值，即特殊的undefined。
                在使用var声明变量但未对其加以初始化时，这个变量的值就是undefined

            null类型：
                null类型是第二个只有一个值的数据类型，这个类型的值是null。
                从逻辑来看，null值表示一个空对象的指针，而这也证明使用typeof操作符检测null时会返回object

                如果定义的变量准备在将来用于保存对象，那么最好将该变量初始化为null而不是其他值。
                这样，只要检查是否为null值，就可以知道相应的变量是否已经保存了一个对象

                实际上，undefined的值是派生自null值得，因此ECMA-262规定对他们相等性测试要返回true。
                    console.log(undefined == null); // true
                    console.log(undefined === null); // false

            boolean类型：
                boolean类型是ECMAScript中使用的最多的一种类型，该类型只有两个字面值：true和false
                这两个值与数字值不是一回事，因此true不一定等于数字1，而false也不一定等于数字0

                boolean类型的字面量的值true和false是区分大小写的，也就是说，True和False（以及其他的大小写混合形式）
                都不是boolean的值，只是标识符

                虽然boolean类型的字面量的值只有两个，但是ESMAScript中所有类型的值都有与这两个布尔值等价的值。
                要将一个值转换为一个等价的值，可以调用转型函数Boolean()，

                各种数据类型对应的转型规则：
                    数据类型        转换为true的值              转换为false的值
                    Boolean         true                       false
                    String          任何非空字符串              ""（空字符串）
                    Number          任何非零数字值(包括无穷大)   0和NaN
                    Object          任何对象                    null
                    Undefined       n/a                         undefined

            Number类型：
                Number类型使用IEEE754格式来表示整数和浮点数值（浮点数值在某些语言中也被称为双精度值）

                为了支持各种数据类型，ECMA-262定义了不同的数值字面量格式：
                    最基本的数值字面量格式是十进制整数：
                        var intNum = 10;
                    八进制字面值得第一位必须是0：
                        var num1 = 070; // 八进制的56
                        var num2 = 079; // 无效的八进制，解析为79
                        八进制的字面量在严格模式下是无效的，会导致支持该模式的JS引擎抛出错误
                    十六进制的字面量值得前两位必须是0x：
                        var num1 = 0xA; // 十六进制的10
                        var num2 = 0x1f; // 十六进制的31
                    在进行算术计算时，八进制和十六进制表示的数值最终将被转换成十进制数值。
                
                数值范围：
                    ECMAScript能够表示的最小值保存在Number.MIN_VALUE中，在大多数浏览器中，这个值是5e-324，能够表示的最大数值保存在
                    Number.MAX_VALUE中，在大多数浏览器中，这个值是1.7976931348623157e+308，如果某次计算的结果得到了一个超出了JS数值
                    最大范围的值，那么这个数值将会转换成特殊的Infinity值。具体来说，如果这个数是负数，则会被转成-Infinity(负无穷)，
                    如果这个数值是整数，则会被转换成Infinity(正无穷)

                    如果某次计算返回了正或负的Infinity，那么该值将无法参与下一次的运算，因为Infinity是不能够参与计算的数值。
                    要想确定一个数值是不是有穷的（换句话说，是不是位于Number的最大值和最小值之间），可以使用isFinite()函数。
                    这个函数在参数位于Number的最大值和最小值之间返回true。

                    访问Number.NEGATIVE_INFINITY和Number.POSITIVE_INFINITY也可以得到负和正的Infinity值

                NaN：
                    NaN，即非数值(Not a Number)是一个特殊的值，这个数值用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)
                    在ECMAScript中，任何数除以非数值都会返回NaN，因此不会影响其他代码执行。

                    NaN有两个非同寻常的特点：
                        1、任何涉及NaN的操作，都会返回NaN
                        2、NaN与任何值都不相等，包括NaN本身

                    针对这两个特点，ECMAScript定义了isNaN()函数，这个函数接受一个参数，该参数可以使任何类型，而函数会帮我们确定这个参数是否不是数值。
                    isNaN()函数在接收到一个值后，会尝试将这个值转换为数值，某些不是数值的值会直接转换为数值，而任何不能被转换为数值的值都会导致这个函数
                    返回true。

                    isNaN()函数也适用于对象，在基于对象调用isNaN()函数时，会首先调用对象的valueOf()方法，然后确定该方法的返回值是否可以转换为数值。
                    如果不能，则基于这个对象的返回值再调用toString()方法，再测试返回值。而这个过程也是ECMAScript中内置函数和操作符的一般执行过程。

                数值转换：
                    有3个函数可以把非数值转换为数值：Number()、parseInt()和parseFloat()。第一个函数即转型函数Number()可以用于任何数据类型，
                    而另外两个函数则专门用于把字符串转换成数值。

                    Number()函数转换规则：
                        1、如果是Boolean值，true和false将分别被转换为1和0
                        2、如果是数字值，只是简单的传入和返回
                        3、如果是null值，返回0
                        4、如果是undefined，返回NaN
                        5、如果是字符串，则遵循以下规则：
                            * 如果字符串中只包含数字（包括前面带正好和负号的情况），则将其转换为十进制数值。"1"转换为1，"011"转换为11
                            * 如果字符串中包含有效的浮点格式，如"1.1"，则将其转换为对应的浮点值，也会忽略前导0
                            * 如果字符串中包含有效的十六进制格式，则将其转换为相同大小的十进制整数值
                            * 如果字符串是空的（不包含任何字符），则将其转换成0
                            * 如果字符串中包含除上述格式之外的字符，则将其转换成NaN
                        6、如果是对象，则调用对象的valueOf()方法，然后按照前面的规则转换返回的值。如果转换的结果是NaN，则调用对象的toString()，
                        然后再一次按照前面的规则转换返回的字符串值。

                    parseInt()函数：
                        parseInt()函数在转换字符串时，更多的是看其是否符合数值模式。它会忽略字符串前面的空格，直至找到第一个非空格字符。
                        如果第一个字符不是数字字符或者负号，parseInt()就会返回NaN；也就是说parseInt()转换空字符串会返回NaN（Number()转换会返回0）。
                        如果第一个字符是数字字符，parseInt()会继续解析第二个字符，知道解析完成所有后续字符或者遇到了一个非数字字符。
                        如果字符串中的第一个字符是数字字符，parseInt()也能够识别出各种整数格式。也就是说如果字符串以0x开头且后跟数字字符，就会将其当做
                        一个十六进制整数；如果字符串以0开头且后跟有效数字字符，将会将其当做一个八进制数来解析。
                        因此，parseInt()函数的第二个参数可以传转换时使用的基数（多少进制），默认转成十进制数

                    parseFloat()函数：
                        parseFloat()也是从第一个字符（位置0）开始解析每个字符，而且也一直是解析到字符串末尾，或者解析到遇见一个无效的浮点数字字符为止。
                        也就是说，字符串中的第一个小数点是有效的，而第二个小数点就是无效的了，因此他后面的字符串将被忽略。
                        除了第一个小数点之外，parseFloat()与parseInt()的第二个区别是他始终都会忽略前导0，十六进制的字符串始终转换成0，parseFloat()只
                        解析十进制值，没有第二个参数指定进制的用法。
                        如果包含的字符串是一个可解析为整数的数（没有小数点或者小数点后面都是0），parseFloat()会返回整数

            string类型：
                String类型用于表示由0个或多个16位Unicode字符组成的字符序列，即字符串。字符串可以由双引号("")或单引号('')表示。
                用双引号表示的字符串和用单引号表示的字符串完全相同。不过以双引号开头的字符串，必须以双引号结尾，而已单引号开头的字符串必须以单引号结尾。

                字符串字面量：
                    String数据类型包含一些特殊的字符字面量，也叫转义序列，用于表示非法打印字符，或者具有其他用途的字符。
                    \n  换行 ；\t 制表 ；\b 退格 ；\r 回车 ；\f 进纸 ；\\ 斜杠 ；\' 单引号 ；\" 双引号 ；\xnn 以十六进制吗表示的字符
                    \unnnn 以十六进制码表示的一个Unicode字符
                
                字符串的特点：
                    ECMAScript中的字符串是不可变的，也就是说，字符串一旦创建，他们的值就不能改变。要改变某个变量保存的字符串，首先要销毁原来的字符串，
                    然后再用另一个包含新值的字符串填充该变量。

                转换为字符串：
                    要把一个值转换为一个字符串有两种方式。
                    1、toString()方法：
                        数值、布尔值、对象和字符串值都有这个方法，但是null和undefined值没有这个方法
                        多数情况下，toString()方法不用传参数。但是在数值调用toString()方法时可以传递一个参数：输出数值的基数，默认情况下，
                        toString()方法以十进制的格式返回数值的字符串表示。而通过传递基数可以输出以二进制、八进制、十六进制以及其他任意有效
                        进制格式表示的字符串。
                    
                    2、String()转型函数：
                        在不知道要转换的值是不是null或undefined的情况下，还可以使用转型函数String()，这个函数能将任何类型的值转换为字符串。
                        String()函数遵循以下规则：
                            如果值有toString()方法，则调用该方法(没有参数)并返回相应的结果
                            如果值是null，则返回"null"
                            如果值是undefined，则返回"undefined"


        */
        
        
    </script>
</body>
</html>